package com.gitee.wsl.struct.compare.diff.matcher

import com.gitee.wsl.api.Configurable

interface Matcher<T,CONFIG> : Configurable<CONFIG> {
    /**
     * Compute and return the mappings between a provided src and dst AST.
     * The mappings are added as a side effect in the provided mapping store.
     * The provided mapping store is return as well to allow chaining.
     */
    fun match(src: T, dst: T, mappings: MappingStore<T>): MappingStore<T>

    /**
     * Utility method that compute and return the mappings between a provided
     * src and dst AST in a new mapping store.
     *
     * @see .match
     */
    fun match(src: T, dst: T): MappingStore<T> {
        return match(src, dst, MappingStore<T>(src, dst))
    }
}

class CompositeMatcher<T,CONFIG>(val matchers: List<Matcher<T, CONFIG>> = emptyList()) :
    Matcher<T, CONFIG> {

    override fun match(src: T, dst: T, mappings: MappingStore<T>): MappingStore<T> {
        var mappings = MappingStore(mappings)
        for (matcher in matchers)
            mappings = matcher.match(src, dst, mappings)
        return mappings
    }


    fun matchers(): List<Matcher<T, CONFIG>> {
        return matchers
    }

    override fun config(block: CONFIG.() -> Unit) {
        for (matcher in matchers)
            matcher.config(block = block)
    }

}

